package com.reggie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.reggie.dto.DishDto;
import com.reggie.entity.*;
import com.reggie.exception.CustomException;
import com.reggie.mapper.CategoryMapper;
import com.reggie.mapper.DishMapper;
import com.reggie.service.DishFlavorService;
import com.reggie.service.DishService;
import com.reggie.service.SetmealDishService;
import com.reggie.service.ShoppingCartService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService {
    @Autowired
    private DishFlavorService dishFlavorService;
    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private SetmealDishService setmealDishService;
    @Autowired
    private ShoppingCartService shoppingCartService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveDish(DishDto dishDto) {
        this.save(dishDto);
        List<DishFlavor> flavors = dishDto.getFlavors();
        if (flavors != null) {
            flavors.forEach(f -> {
                f.setDishId(dishDto.getId());
            });
            dishFlavorService.saveBatch(flavors);
        }
    }

    @Override
    public Page<DishDto> pageDish(int page, int pageSize, String name) {
        Page<Dish> page1 = new Page<>(page, pageSize);
        LambdaQueryWrapper<Dish> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.like(StringUtils.isNotBlank(name), Dish::getName, name);
        lambdaQueryWrapper.orderByDesc(Dish::getUpdateTime);
        this.page(page1, lambdaQueryWrapper);
        Page<DishDto> dishDtoPage = new Page<>();
        //先将Page里除了数据之外的东西复制一次
        BeanUtils.copyProperties(page1, dishDtoPage, "records");
        //拿到之前的Dish数据
        List<Dish> records = page1.getRecords();
        //创建一个新的DishDto集合
        List<DishDto> dishDtos = new ArrayList<>();
        Set<Long> ids = new HashSet<>();
        records.forEach(s -> ids.add(s.getCategoryId()));
        List<Category> categories = categoryMapper.selectBatchIds(ids);
        //遍历Dish数据，将每行数据复制到DishDto里
        records.forEach(record -> {
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(record, dishDto);
            //再拿categoryId去数据库里查，把名称封到DishDto里
            Long categoryId = dishDto.getCategoryId();
            categories.forEach(category -> {
                if (category.getId().equals(categoryId))
                    dishDto.setCategoryName(category.getName());
            });
            //把DishDto装进List集合中
            dishDtos.add(dishDto);
        });
        //把DishDto集合装回Page对象
        dishDtoPage.setRecords(dishDtos);
        return dishDtoPage;
    }

    @Override
    public DishDto findById(Long id) {
        Dish byId = this.getById(id);
        DishDto dishDto = new DishDto();
        BeanUtils.copyProperties(byId, dishDto);
        LambdaQueryWrapper<DishFlavor> dishFlavorLambdaQueryWrapper = new LambdaQueryWrapper<>();
        dishFlavorLambdaQueryWrapper.eq(dishDto.getId() != null, DishFlavor::getDishId, id);
        List<DishFlavor> list = dishFlavorService.list(dishFlavorLambdaQueryWrapper);
        dishDto.setFlavors(list);
        return dishDto;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateDish(DishDto dishDto) {
        /*this.updateById(dishDto);
        List<DishFlavor> flavors = dishDto.getFlavors();
        LambdaQueryWrapper<DishFlavor> dishFlavorLambdaQueryWrapper = new LambdaQueryWrapper<>();
        dishFlavorLambdaQueryWrapper.eq(DishFlavor::getDishId,dishDto.getId());
        dishFlavorService.remove(dishFlavorLambdaQueryWrapper);
        flavors.forEach(dishFlavor -> dishFlavor.setDishId(dishDto.getId()));
        dishFlavorService.saveBatch(flavors);*/
        Dish dish = this.getById(dishDto.getId());
        //如果修改了菜品价格，则将购物车里的菜品价格也给修改了
        if (!dish.getPrice().equals(dishDto.getPrice())) {
            LambdaUpdateWrapper<ShoppingCart> shoppingCartLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            shoppingCartLambdaUpdateWrapper.eq(ShoppingCart::getDishId, dishDto.getId());
            shoppingCartLambdaUpdateWrapper.set(ShoppingCart::getAmount, dishDto.getPrice().divide(BigDecimal.valueOf(100)));
            shoppingCartService.update(shoppingCartLambdaUpdateWrapper);
        }
        this.updateById(dishDto);
        LambdaQueryWrapper<DishFlavor> dishFlavorLambdaQueryWrapper = new LambdaQueryWrapper<>();
        dishFlavorLambdaQueryWrapper.eq(dishDto.getId() != null, DishFlavor::getDishId, dishDto.getId());
        dishFlavorService.remove(dishFlavorLambdaQueryWrapper);
        dishDto.getFlavors().forEach(f -> {
            f.setDishId(dishDto.getId());
            f.setId(null);
        });
        dishFlavorService.saveBatch(dishDto.getFlavors());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteDish(List<Long> ids) {
        LambdaQueryWrapper<DishFlavor> dishFlavorLambdaQueryWrapper = new LambdaQueryWrapper<>();
        LambdaQueryWrapper<SetmealDish> setmealDishLambdaQueryWrapper = new LambdaQueryWrapper<>();
        dishFlavorLambdaQueryWrapper.in(DishFlavor::getDishId, ids);
        setmealDishLambdaQueryWrapper.in(SetmealDish::getDishId, ids);
        long count = setmealDishService.count(setmealDishLambdaQueryWrapper);
        if (count > 0)
            throw new CustomException("有菜品在套餐中使用！请先删除使用该菜品的套餐");
        dishFlavorService.remove(dishFlavorLambdaQueryWrapper);
        LambdaQueryWrapper<ShoppingCart> shoppingCartLambdaQueryWrapper = new LambdaQueryWrapper<>();
        shoppingCartLambdaQueryWrapper.in(ShoppingCart::getDishId, ids);
        shoppingCartService.remove(shoppingCartLambdaQueryWrapper);
        this.removeBatchByIds(ids);
    }

    @Override
    public List<DishDto> listDish(Long categoryId, String name, Integer status) {
        //先将dish给查询出来
        LambdaQueryWrapper<Dish> dishLambdaQueryWrapper = new LambdaQueryWrapper<>();
        dishLambdaQueryWrapper.eq(categoryId != null, Dish::getCategoryId, categoryId);
        dishLambdaQueryWrapper.eq(status != null, Dish::getStatus, status);
        dishLambdaQueryWrapper.like(StringUtils.isNotBlank(name), Dish::getName, name);
        dishLambdaQueryWrapper.orderByAsc(Dish::getUpdateTime);
        //获取dish集合
        List<Dish> list = this.list(dishLambdaQueryWrapper);
        //用来封装最终数据dishdto集合
        List<DishDto> dishDtoList = new ArrayList<>();
        //获取所有的dishId
        Set<Long> dishIds = new HashSet<>();
        list.forEach(dish -> dishIds.add(dish.getId()));
        //根据dishids把所有的口味查出来
        List<DishFlavor> dishFlavors = dishFlavorService.list(new LambdaQueryWrapper<DishFlavor>().in(DishFlavor::getDishId, dishIds));
        //遍历dish集合
        list.forEach(dish -> {
            //将dish的所有数据复制到dishdto里
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(dish, dishDto);
            //先给一个空的口味集合
            dishDto.setFlavors(new ArrayList<>());
            dishFlavors.forEach(dishFlavor -> {
                //遍历口味集合，如果符合条件就把当前口味添加到当前dishDto里
                if (dishFlavor.getDishId().equals(dish.getId())) {
                    dishDto.getFlavors().add(dishFlavor);
                }
            });
            //将当前dishdto添加到集合里
            dishDtoList.add(dishDto);
        });
        return dishDtoList;
    }
}
